package com.ruoyi.tj.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.ruoyi.common.utils.StringUtils;

import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
 * @title: MyBeanSerializerModifier
 * @Author junyu
 * 旧巷里有一个穿着白衬衫笑起来如太阳般温暖我的少年。
 * 记忆里有一个穿着连衣裙哭起来如孩子般讨人喜的女孩。
 * 他说，哪年树弯了腰，人见了老，桃花落了白发梢，他讲的笑话她还会笑，那便是好。
 * 她说，哪年国改了号，坟长了草，地府过了奈何桥，她回头看时他还在瞧，就不算糟。
 * @Date: 2020/9/12 16:44
 * @Version 1.0
 */
public class MyBeanSerializerModifier extends BeanSerializerModifier {

    private MyNullStringJsonSerializer myNullStringJsonSerializer;
    private MyNullArrayJsonSerializer MyNullArrayJsonSerializer;
    private MyNullObjectJsonSerializer MyNullObjectJsonSerializer;
    private MyNullJsonSerializer myNullJsonSerializer;

    private NumericBooleanSerializer booleanSerializer;

    public MyBeanSerializerModifier(){
        myNullStringJsonSerializer = new MyNullStringJsonSerializer();
        MyNullArrayJsonSerializer = new MyNullArrayJsonSerializer();
        MyNullObjectJsonSerializer =  new MyNullObjectJsonSerializer();
        myNullJsonSerializer = new MyNullJsonSerializer();
        booleanSerializer = new NumericBooleanSerializer();
    }

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
                                                     List<BeanPropertyWriter> beanProperties) {
        // 循环所有的beanPropertyWriter
        beanProperties.forEach(writer ->{
            // 判断字段的类型
            if (isArrayType(writer)) {
                //给writer注册一个自己的nullSerializer
                writer.assignNullSerializer(MyNullArrayJsonSerializer);
            } else if (isObjectType(writer)) {
                writer.assignNullSerializer(MyNullObjectJsonSerializer);
            } else if (isStringType(writer)) {
                writer.assignNullSerializer(myNullStringJsonSerializer);
            } else if (isPrimitiveType(writer)) {
                writer.assignNullSerializer(myNullJsonSerializer);
            }
        });
        return beanProperties;
    }

    // 判断是否是boolean类型
    private boolean isPrimitiveType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return clazz.isPrimitive();
    }

    // 判断是否是string类型
    private boolean isStringType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return clazz.equals(String.class);
    }

    // 判断是否是对象类型
    private boolean isObjectType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return !clazz.isPrimitive() && !clazz.equals(String.class)
                && clazz.isAssignableFrom(Object.class);
    }
    // 判断是否是集合类型
    protected boolean isArrayType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return clazz.isArray() || clazz.equals(List.class) || clazz.equals(Set.class);
    }

    protected boolean isBoolean(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return clazz.equals(Boolean.class);
    }

    class MyNullJsonSerializer extends JsonSerializer<Object> {

        @Override
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
            if (value == null) {
                jgen.writeNull();
            }
        }
    }


    class MyNullStringJsonSerializer extends JsonSerializer<Object>{

        @Override
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
            if (value == null) {
                jgen.writeString(StringUtils.EMPTY);
            }
        }
    }

    class MyNullArrayJsonSerializer extends JsonSerializer<Object>{

        @Override
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
            if (value == null) {
                jgen.writeStartArray();
                jgen.writeEndArray();
            }
        }
    }

    class MyNullObjectJsonSerializer extends JsonSerializer<Object>{

        @Override
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
            if (value == null) {
                jgen.writeStartObject();
                jgen.writeEndObject();
            }
        }
    }

}